home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
disk
/
cluster2.zip
/
SOURCE.ZIP
/
VERTMENU.BU
< prev
Wrap
Text File
|
1996-07-06
|
15KB
|
341 lines
$COMPILE UNIT ".\VERTMENU.PBU"
$CODE SEG "SCRNLIB"
$CPU 8086 ' Make compatible with XT systems
$LIB ALL OFF ' Turn off all PowerBASIC libraries
$ERROR ALL OFF ' Turn off all PowerBASIC error checking
$OPTIMIZE SIZE ' Optimize for smaller code
DEFINT A-Z ' Required for all numeric functions, forces PB to not
' include floating point in UNIT (makes it smaller)
'+-----------------------------------------------------------------+
'| This component of PB3BOXES is Copyright Nathan C. Durland III |
'| All rights reserved |
'+-----------------------------------------------------------------+
$INCLUDE ".\PB3BOXES.HDR"
SUB VerticalMenu(MenuList$(), Choice%, BYVAL DisplayMode%, _
BYVAL HighAttr%, BYVAL MenuTimer%, _
BYVAL ProcTimer%, BYVAL ProcAddr AS DWORD) LOCAL PUBLIC
'╒════════════════════════════════════════════════════════════════════════════╕
'│ This is the routine to call for simple one-choice vertical menus │
'│ │
'│ See TagMenu for a more complete definition of the paramters │
'╘════════════════════════════════════════════════════════════════════════════╛
Junk$ = "ONE"
CALL TagMenu(MenuList$(), Junk$, DisplayMode%, _
HighAttr%,MenuTimer%, ProcTimer%, ProcAddr)
Choice% = INSTR(junk$,"1")
END SUB
SUB TagMenu(MenuList$(), TagList$, BYVAL DisplayMode%, _
BYVAL HighAttr%, BYVAL MenuTimeOut%, _
BYVAL ProcTimeOut%, BYVAL ProcAddr AS DWORD) PUBLIC
'╒════════════════════════════════════════════════════════════════════════════╕
'│ This routine will display a list of items -- MenuList$() -- on the screen │
'│ and will toggle the corresponding element of TagMenuChoice%() from %True │
'│ to %False, as appropriate. Each tagged entry will have a "" next to it. │
'│ │
'│ The user can toggle the choice of an item by pressing the INS or the │
'│ DEL key. CTRL-INS & CTRL-DEL will select/deselect all items. │
'│ │
'│ The ENTER key will terminate the call. ESC also terminates, but will set │
'│ the ItemsTagged% parameter to 0. │
'│ │
'│ - The Home Key will move the menu to the top, │
'│ - The End key will proceed to the bottom. │
'╞════════════════════════════════════════════════════════════════════════════╡
'│Using TagMenu really involves 3 CALL statements: │
'│ 1. call MakeBox to create a box to place the menu in. Make sure the │
'│ box is at least 4 characters wider than the widest menu list item. │
'│ 2. call TagMenu. │
'│ 3. call RemoveBox. │
'╞════════════════════════════════════════════════════════════════════════════╡
'│PowerBASIC calling parameters: │
'│ │
'│ MenuList$() -- the items to display on the screen. The last element in │
'│ the array must be set to "" │
'│ TagList$ -- A string of "0" and "1", with a lenght equal to the │
'│ number of items in the menu. "1" corresponds to a │
'│ tagged item. If this string is eqal to "ONE" when this │
'│ routine is called, then the user will only be allowed │
'│ to make one choice. │
'│ DisplayMode% -- if 0, then the choices are centered in the box. │
'│ -- if 1, the choices are left justified │
'│ -- if 2, the choices are left justified, and have a │
'│ letter next to them. Pressing the letter highlights │
'│ that choice. The letters are based on the items position│
'│ in the menu screen │
'│ HighAttr% -- The color attribute to use for highlighted items │
'│ MenuTimeOut% -- a timeout value (seconds). If no choice is made before │
'│ this runs out, the menu exits and returns Choice% = 0. │
'│ Set MenuTimer% to 0 for no time out. A message is │
'│ displayed on the bottom of the screen. │
'│ ProcTimeOut% -- Another timer. This counts how long before the routine │
'│ pointed to by ProcAddr should be called. Set it to 0 │
'│ for no timed routine. Handy for print spoolers, etc │
'│ ProcAddr -- A DWORD value returned by CODEPTR32 that points to a │
'│ routine that you'd like done every ProcTimeOut% seconds │
'╘════════════════════════════════════════════════════════════════════════════╛
JustOne% = (TagList$ = "ONE")
MenuRow% = BoxParms%(CurrentBox%,1) ' Get current box size & paramters
MenuCol% = BoxParms%(CurrentBox%,2)
MenuRows% = BoxParms%(CurrentBox%,3)
MenuCols% = BoxParms%(CurrentBox%,4)
MenuAttr% = BoxParms%(CurrentBox%,5)
'╒════════════════════════════════════════════════════════════════╕
'│ We're might have to change these, so we want to save them now │
'╘════════════════════════════════════════════════════════════════╛
OldMenuCol% = MenuCol%
OldMenuRows% = MenuRows%
OldMenuCols% = MenuCols%
IF BoxParms%(CurrentBox%,6) > 0 THEN ' Account for the border
INCR MenuRow%,1
DECR MenuRows%,2
INCR MenuCol%,1
DECR MenuCols%,2
END IF
MenuLen% = MenuRows% ' set some other vars that we need
ARRAY SCAN MenuList$(1), = "", TO ItemCnt%
IF ItemCnt% = 0 THEN
ItemCnt% = UBOUND(MenuList$())
ELSE
DECR ItemCnt%,1
END IF
IF ItemCnt% < MenuLen% THEN
MenuLen% = ItemCnt%
MenuRows% = ItemCnt%
BoxParams%(CurrentBox%,3) = ItemCnt% + 2 ' set this so that only the area
END IF ' with menu items on it scrolls
IF DisplayMode% = 2 THEN ' put the letters in place for
FOR x% = 1 TO MenuLen% ' the menu
CALL PrtBox(x%,1,CHR$(64+x%,32),HighAttr%)
NEXT x%
BoxParms%(CurrentBox%,2) = MenuCol% + 1
BoxParms%(CurrentBox%,4) = MenuCol% - 1 ' change this so letters don't
MenuCol% = MenuCol% + 2 ' scroll with box
MenuCols% = MenuCols% - 2
END IF
TagList$ = TagList$ + STRING$(ItemCnt%,"0")
TagList$ = LEFT$(TagList$,ItemCnt%)
ItemPtr% = 1 'Array member currently pointed to
curntpos% = 1 'Position in the on-screen menu
TheCnt% = ItemsTagged%
TopItem% = 1
BottomItem% = MenuLen%
GOSUB FillTagMenu
MenuTimer! = -1
ProcTimer! = -1
IF MenuTimeOut% > 0 THEN MenuTimer! = TIMER + MenuTimeOut%
IF ProcTimeOut% > 0 THEN ProcTimer! = TIMER + ProcTimeOut%
Terminated% = %False
WHILE NOT Terminated%
' Highlight the current item
CALL QATTR((MenuRow%+curntPos%-1), MenuCol%,1, MenuCols%, HighAttr%)
' Get a keypress from the user, and do other stuff while we are waiting
WHILE NOT INSTAT
IF (MenuTimer! > 0) AND (TIMER > MenuTimer!) THEN
TagList$ = STRING$(ItemCnt%,"0")
EXIT SUB
END IF
IF (ProcTimer! > 0) AND (TIMER > ProcTimer!) THEN
CALL DWORD ProcAddr
ProcTimer! = TIMER + ProcTimeOut%
END IF
WEND
a$ = INKEY$ ' get the key, then
IF LEN(a$) = 1 THEN ' assign the ascii value to
ans% = ASC(UCASE$(a$)) ' our response.
ELSE ' for two byte keys, response is
ans% = 255 + ASC(RIGHT$(a$,1)) ' 255 + the ascii value of
END IF ' the second byte
IF MenuTimeOut% > 0 THEN MenuTimer! = TIMER + MenuTimeOut%
IF ProcTimeOut% > 0 THEN ProcTimer! = TIMER + ProcTimeOut%
IF JustOne% THEN ' When choosing just one item, we
IF ans% = %Space THEN ans% = 0 ' ignore space, plus, minus
IF ans% = %InsKey THEN ans% = 0 ' ctrl+ and ctrl-
IF ans% = %DelKey THEN ans% = 0
IF ans% = %CtrlIns THEN ans% = 0
IF ans% = %CtrlDel THEN ans% = 0
END IF
IF Ans% = 0 THEN ITERATE
'We've got a key press, so Un-highlight the current item
CALL QATTR((MenuRow%+curntPos%-1), MenuCol%,1, MenuCols%, MenuAttr%)
IF MID$(TagList$,ItemPtr%,1) = "1" THEN CALL PrtBox(curntpos%,1,"",HighAttr%)
' Now process the keystroke.
IF ans% = %Enter THEN ' we're done, get out
Terminated% = %True
IF JustOne% THEN
MID$(TagList$,ItemPtr%,1) = "1"
ELSE
ItemsTagged% = TALLY(TagList$,"1")
IF ItemsTagged% = 0 THEN MID$(TagList$,ItemPtr%,1) = "1"
END IF
ELSEIF ans% = %Esc THEN ' We're abandoning.
TagList$ = STRING$(ItemCnt%,"0")
Terminated% = %True
ELSEIF (ans% = %DelKey) OR _ ' del or minus untags
(ans% = ASC("-")) THEN
MID$(TagList$,ItemPtr%,1) = "0"
CALL PrtBox(curntpos%,1," ",-1)
IF (ItemPtr% < ItemCnt%) AND _ ' and go to next item
(curntpos% < MenuLen%) THEN
INCR curntpos%, 1
INCR ItemPtr%, 1
END IF
ELSEIF (ans% = %InsKey) OR _ ' insert or Plus tags
(ans% = ASC("+")) THEN
MID$(TagList$,ItemPtr%,1) = "1"
CALL PrtBox(curntpos%,1,"",HighAttr%)
IF (ItemPtr% < ItemCnt%) AND _ ' and go to next item
(curntpos% < MenuLen%) THEN
INCR curntpos%, 1
INCR ItemPtr%, 1
END IF
ELSEIF ans% = %Space THEN ' Space is a toggle
a$ = MID$(TagList$,ItemPtr%,1)
IF a$ = "0" THEN
MID$(TagList$,ItemPtr%,1) = "1"
CALL PrtBox(curntpos%,1,"",HighAttr%)
ELSE
MID$(TagList$,ItemPtr%,1) = "0"
CALL PrtBox(curntpos%,1," ",MenuAttr%)
END IF
IF (ItemPtr% < ItemCnt%) AND _ ' and go to next item
(curntpos% < MenuLen%) THEN
INCR curntpos%, 1
INCR ItemPtr%, 1
END IF
ELSEIF ans% = %PgUp THEN ' page up
IF TopItem% > 1 Then
TopItem% = TopItem% - MenuLen%
IF TopItem% < 1 THEN TopItem% = 1
BottomItem% = TopItem% + MenuLen%
ItemPtr% = TopItem%
curntpos% = 1
GOSUB FillTagMenu
END IF
ELSEIF ans% = %PgDn THEN ' page down
IF BottomItem% < ItemCnt% Then
BottomItem% = BottomItem% + MenuLen% + 1
IF BottomItem% > ItemCnt% THEN BottomItem% = ItemCnt% + 1
TopItem% = BottomItem% - MenuLen%
ItemPtr% = TopItem%
curntpos% = 1
GOSUB FillTagMenu
END IF
ELSEIF ans% = %UpArrow THEN ' go up one item
IF curntpos% > 1 THEN ' not at top, so it's easy
DECR curntpos%, 1
DECR ItemPtr%, 1
ELSEIF ItemPtr% > 1 THEN 'if we aren't at the first item
CALL ScrollBox(0,1) ' scroll the box down
DECR ItemPtr%,1 ' and adjust the pointers
DECR TopItem%,1 ' the line will get redisplayed
DECR BottomItem%,1 ' at the top of the loop
IF DisplayMode% = 0 THEN ' center the item
CALL PrtBox(curntpos%,0,MenuList$(ItemPtr%),-1)
ELSE ' left justify
CALL PrtBox(curntpos%,2,MenuList$(ItemPtr%),-1)
END IF
IF MID$(TagList$,ItemPtr%,1) = "1" THEN CALL PrtBox(curntpos%,1,"",HighAttr%)
END IF
ELSEIF ans% = %DownArrow THEN ' go down an item
IF curntpos% < MenuLen% THEN ' not at bottom, so it's easy
INCR curntpos%, 1
INCR ItemPtr%, 1
ELSEIF ItemPtr% < ItemCnt% THEN 'if this isn't the last item
CALL ScrollBox(1,1) ' Scroll the box up, and adjust
INCR ItemPtr%,1 ' the pointers. The line will
INCR TopItem%,1 ' redisplay at the top of the
INCR BottomItem%,1 ' keyin loop
IF DisplayMode% = 0 THEN ' center the item
CALL PrtBox(curntpos%,0,MenuList$(ItemPtr%),-1)
ELSE ' left justify
CALL PrtBox(curntpos%,2,MenuList$(ItemPtr%),-1)
END IF
IF MID$(TagList$,ItemPtr%,1) = "1" THEN CALL PrtBox(curntpos%,1,"",HighAttr%)
END IF
ELSEIF ans% = %HomeKey THEN ' go to top of item list
ItemPtr% = 1
curntpos% = 1
TopItem% = 1
BottomItem% = TopItem% + MenuLen%
GOSUB FillTagMenu
ELSEIF ans% = %EndKey THEN ' go to bottom of item list
ItemPtr% = ItemCnt%
curntpos% = MenuLen%
BottomItem% = ItemCnt%
TopItem% = BottomItem% - MenuLen%
GOSUB FillTagMenu
ELSEIF ans% = %CtrlDel THEN ' Untag everything
TagList$ = STRING$(ItemCnt%,"0")
GOSUB FillTagMenu
ELSEIF ans% = %CtrlIns THEN ' tag everything
TagList$ = STRING$(ItemCnt%,"1")
GOSUB FillTagMenu
ELSE
IF (ans% > 64) AND (ans% < 91) THEN
a% = TopItem% + (ans% - 65)
MID$(TagList$,a%,1) = "1"
IF JustOne% THEN Terminated% = %True
curntpos% = a%
END IF
END IF
WEND
BoxParms%(CurrentBox%,2) = OldMenuCol%
BoxParms%(CurrentBox%,3) = OldMenuRows%
BoxParms%(CurrentBox%,4) = OldMenuCols%
EXIT SUB 'Good bye!
FillTagMenu:
'╒═════════════════════════════════════════════════════════════════════════╕
'│This sub fills the empty box with menu items, based on the current value │
'│of ItemPtr% and MenuLen% │
'╘═════════════════════════════════════════════════════════════════════════╛
IF TopItem% < 1 THEN TopItem% = 1
BottomItem% = TopItem% + MenuLen% - 1
IF BottomItem% > ItemCnt% THEN BottomItem% = ItemCnt%
CALL ClearBox(-1,-1)
FOR ThisItem% = TopItem% to BottomItem%
x% = ThisItem% - TopItem% + 1
IF DisplayMode% = 0 THEN ' center the item
CALL PrtBox(x%,0,MenuList$(ThisItem%),-1)
ELSE ' left justify
CALL PrtBox(x%,2,MenuList$(ThisItem%),-1)
END IF
IF MID$(TagList$,ThisItem%,1) = "1" THEN CALL PrtBox(x%,1,"",HighAttr%)
NEXT ThisItem%
RETURN
END SUB